package com.link2room.soundwave.service.impl;

import com.link2room.bumblebee.dto.param.base.PmsReservationOptionParamDto;
import com.link2room.bumblebee.dto.result.base.PmsReservationOptionDto;
import com.link2room.common.constant.DefaultValue;
import com.link2room.common.jpa.result.QueryResult;
import com.link2room.common.service.ICommonService;
import com.link2room.common.util.*;
import com.link2room.enums.exception.SoundwaveSysExceptionEnum;
import com.link2room.jetfire.dto.result.base.GcOrderCouponDto;
import com.link2room.jetfire.dto.result.base.ReservationBaseDto;
import com.link2room.jetfire.dto.result.base.ReservationPriceDto;
import com.link2room.soundwave.constant.YhPmsConstant;
import com.link2room.soundwave.entity.L2RYhMember;
import com.link2room.soundwave.exception.SoundwaveException;
import com.link2room.soundwave.feign.bumblebee.PmsReservationOptionFeignService;
import com.link2room.soundwave.service.IYhPmsBaseService;
import com.link2room.soundwave.util.YhPmsUtil;
import org.apache.http.Header;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import yuheng.pms.param.YhBasenfoRequestParamDto;
import yuheng.pms.param.YhReservationRequestParamDto;
import yuheng.pms.result.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;

/**
 * Created by sss on 2017/6/7.
 */
@Service("yhPmsBaseService")
public class YhPmsBaseServiceImpl implements IYhPmsBaseService {
    @Autowired
    private PmsReservationOptionFeignService pmsReservationOptionFeignService;
    @Resource
    private ICommonService commonService;

    @Override
    public QueryResult<YhHotelInfoDto> getYhPmsHotelList(String lhotelGroupCode,
                                                  String pmsHotelGroupCode,
                                                  Integer currentPage,
                                                  Integer pageSize) throws Exception {
        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/MinReserve/GetHotelList";
        YhBasenfoRequestParamDto yhBasenfoRequestParamDto=new YhBasenfoRequestParamDto();
        yhBasenfoRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhBasenfoRequestParamDto.setPageIndex(currentPage);
        yhBasenfoRequestParamDto.setPageSize(pageSize);

        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        String responseBody=HttpUtil.httpPost(uri,yhBasenfoRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        if(map.get("Success")!=null) {
            if(true==(boolean)map.get("Success")){
                QueryResult<YhHotelInfoDto> yhHotelInfoDtoQueryResult=new QueryResult<>();
                List<YhHotelInfoDto> yhHotelInfoDtoList=new ArrayList<>();
                List<Map<String,Object>> dataMapList=(List<Map<String,Object>>)map.get("Data");
                YhHotelInfoDto yhHotelInfoDto;
                for(Map<String,Object> dataMap:dataMapList){
                    yhHotelInfoDto=new YhHotelInfoDto();
                    yhHotelInfoDto.setHotelCode((String) dataMap.get("HotelCode"));
                    yhHotelInfoDto.setGroupCode((String) dataMap.get("GroupCode"));
                    yhHotelInfoDto.setMinRoomRate((String) dataMap.get("MinRoomRate"));
                    yhHotelInfoDto.setHotelAddress((String) dataMap.get("HotelAddress"));
                    yhHotelInfoDto.setHotelFullName((String) dataMap.get("HotelFullName"));
                    yhHotelInfoDto.setUserName((String) dataMap.get("UserName"));
                    yhHotelInfoDtoList.add(yhHotelInfoDto);
                }
                yhHotelInfoDtoQueryResult.setResultlist(yhHotelInfoDtoList);
                yhHotelInfoDtoQueryResult.setCurrentPage(currentPage);
                yhHotelInfoDtoQueryResult.setTotalrecord((Integer)map.get("TotalCount"));
                return yhHotelInfoDtoQueryResult;
            }else {
                throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_HOTELLIST_ERROR,(String)map.get("Message"));
            }
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_HOTELLIST_ERROR,responseBody);
        }
    }

    @Override
    public QueryResult<YhRmtypeDto> getYhRmtypeList(String lhotelGroupCode,
                                             String pmsHotelGroupCode,
                                             String pmsHotelCode,
                                             Integer currentPage,
                                             Integer pageSize)throws Exception{
        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/MinReserve/GetRoomTypeList";
        YhBasenfoRequestParamDto yhBasenfoRequestParamDto=new YhBasenfoRequestParamDto();
        yhBasenfoRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhBasenfoRequestParamDto.setHotelCode(pmsHotelCode);
        yhBasenfoRequestParamDto.setPageIndex(currentPage);
        yhBasenfoRequestParamDto.setPageSize(pageSize);
        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        String responseBody=HttpUtil.httpPost(uri,yhBasenfoRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        if(map.get("Success")!=null) {
            if (true == (boolean) map.get("Success")) {
                QueryResult<YhRmtypeDto> yhRmtypeDtoQueryResult = new QueryResult<>();
                List<YhRmtypeDto> yhRmtypeDtoList = new ArrayList<>();
                List<Map<String, Object>> dataMapList = (List<Map<String, Object>>) map.get("Data");
                YhRmtypeDto yhRmtypeDto;
                for (Map<String, Object> dataMap : dataMapList) {
                    yhRmtypeDto = new YhRmtypeDto();
                    yhRmtypeDto.setHotelCode((String) dataMap.get("HotelCode"));
                    yhRmtypeDto.setGroupCode((String) dataMap.get("GroupCode"));
                    yhRmtypeDto.setDescription((String) dataMap.get("Description"));
                    yhRmtypeDto.setEnglishDescription((String) dataMap.get("EnglishDescription"));
                    yhRmtypeDto.setRoomType((String) dataMap.get("RoomType"));
                    yhRmtypeDto.setUserName((String) dataMap.get("UserName"));
                    yhRmtypeDtoList.add(yhRmtypeDto);
                }
                yhRmtypeDtoQueryResult.setCurrentPage(currentPage);
                yhRmtypeDtoQueryResult.setTotalrecord((Integer) map.get("TotalCount"));
                yhRmtypeDtoQueryResult.setResultlist(yhRmtypeDtoList);
                return yhRmtypeDtoQueryResult;
            } else {
                throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_RMTYPELIST_ERROR, (String) map.get("Message"));
            }
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_RMTYPELIST_ERROR, responseBody);
        }
    }

    @Override
    public List<YhRmtypeAvailDto> getYhRoomStockList(String lhotelGroupCode,
                                                     String pmsHotelGroupCode,
                                                     String pmsHotelCode,
                                                     String pmsRmtype,
                                                     String businessStart,
                                                     String businessEnd) throws Exception {
        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/Cms/GetRoomStockList";
        YhBasenfoRequestParamDto yhBasenfoRequestParamDto=new YhBasenfoRequestParamDto();
        yhBasenfoRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhBasenfoRequestParamDto.setHotelCode(pmsHotelCode);
        yhBasenfoRequestParamDto.setRoomType(pmsRmtype);
        yhBasenfoRequestParamDto.setChannelCode("lfwx");
        yhBasenfoRequestParamDto.setStartDate(businessStart);
        yhBasenfoRequestParamDto.setEndDate(businessEnd);
        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        String responseBody=HttpUtil.httpPost(uri,yhBasenfoRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        if(map.get("Success")!=null){
            if(true==(boolean)map.get("Success")){
                List<Map<String,Object>> dataMapList=(List<Map<String,Object>>)map.get("Data");
                return Optional.ofNullable(dataMapList).map(list->list.stream().map(event->{
                    YhRmtypeAvailDto yhRmtypeAvailDto=new YhRmtypeAvailDto();
                    yhRmtypeAvailDto.setHotelCode((String) event.get("HotelCode"));
                    yhRmtypeAvailDto.setGroupCode((String) event.get("GroupCode"));
                    yhRmtypeAvailDto.setBusinessDate(DateUtil.parseDateStandardFormat((String) event.get("BusinessDate")));
                    yhRmtypeAvailDto.setCurrentQuantity((Integer) event.get("CurrentQuantity"));
                    yhRmtypeAvailDto.setRoomType((String) event.get("RoomType"));
                    yhRmtypeAvailDto.setTodayDepartureQuantity((Integer) event.get("TodayDepartureQuantity"));
                    yhRmtypeAvailDto.setTotalQuantity((Integer) event.get("TotalQuantity"));
                    yhRmtypeAvailDto.setOooQuantity((Integer) event.get("OooQuantity"));
                    return yhRmtypeAvailDto;
                }).collect(Collectors.toList())).orElse(null);
            }else {
                throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_RMTYPEAVAIL_ERROR,responseBody);
            }
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_RMTYPEAVAIL_ERROR,responseBody);
        }
    }

    @Override
    public List<YhRmtypeAvailDto> getYhRoomStockListDirect(String lhotelGroupCode,
                                                         String pmsHotelGroupCode,
                                                         String pmsHotelCode,
                                                         String pmsRmtype,
                                                         String businessStart,
                                                         String businessEnd
    ) throws Exception {
        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/MinReserve/SingleTrialFitReserve";
        YhBasenfoRequestParamDto yhBasenfoRequestParamDto=new YhBasenfoRequestParamDto();
        yhBasenfoRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhBasenfoRequestParamDto.setHotelCode(pmsHotelCode);
        yhBasenfoRequestParamDto.setRoomType(pmsRmtype);
        yhBasenfoRequestParamDto.setStartDate(businessStart);
        yhBasenfoRequestParamDto.setEndDate(businessEnd);
        yhBasenfoRequestParamDto.setChannelCode("lfwx");
        yhBasenfoRequestParamDto.setRoomQuantity(1);
        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        String responseBody=HttpUtil.httpPost(uri,yhBasenfoRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        if(map.get("Success")!=null) {
            if (true == (boolean) map.get("Success")) {
                List<YhRmtypeAvailDto> yhRmtypeAvailDtos = new ArrayList<>();
                List<Map<String, Object>> dataMapList = (List<Map<String, Object>>) map.get("Data");
                YhRmtypeAvailDto yhRmtypeAvailDto;
                for (Map<String, Object> dataMap : dataMapList) {
                    yhRmtypeAvailDto = new YhRmtypeAvailDto();
                    yhRmtypeAvailDto.setHotelCode((String) dataMap.get("HotelCode"));
                    yhRmtypeAvailDto.setGroupCode((String) dataMap.get("GroupCode"));
                    yhRmtypeAvailDto.setBusinessDate(DateUtil.parseDateStandardFormat((String) dataMap.get("BusinessDate")));
                    yhRmtypeAvailDto.setCurrentQuantity((Integer) dataMap.get("CurrentQuantity"));
                    yhRmtypeAvailDto.setRoomType((String) dataMap.get("RoomType"));
                    yhRmtypeAvailDtos.add(yhRmtypeAvailDto);
                }
                return yhRmtypeAvailDtos;
            } else {
                if (map.get("Data") != null) {
                    List<YhRmtypeAvailDto> yhRmtypeAvailDtos = new ArrayList<>();
                    List<Map<String, Object>> dataMapList = (List<Map<String, Object>>) map.get("Data");
                    YhRmtypeAvailDto yhRmtypeAvailDto;
                    for (Map<String, Object> dataMap : dataMapList) {
                        yhRmtypeAvailDto = new YhRmtypeAvailDto();
                        yhRmtypeAvailDto.setHotelCode((String) dataMap.get("HotelCode"));
                        yhRmtypeAvailDto.setGroupCode((String) dataMap.get("GroupCode"));
                        yhRmtypeAvailDto.setBusinessDate(DateUtil.parseDateStandardFormat((String) dataMap.get("BusinessDate")));
                        yhRmtypeAvailDto.setCurrentQuantity((Integer) dataMap.get("CurrentQuantity"));
                        yhRmtypeAvailDto.setRoomType((String) dataMap.get("RoomType"));
                        yhRmtypeAvailDtos.add(yhRmtypeAvailDto);
                    }
                    return yhRmtypeAvailDtos;
                }
                throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_RMTYPEAVAIL_ERROR, (String) map.get("Message"));
            }
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_RMTYPEAVAIL_ERROR, responseBody);
        }
    }

    @Override
    public boolean checkYhMemberOrderDouble(String lhotelGroupCode,
                                            String pmsHotelGroupCode,
                                            String pmsHotelCode,
                                            String pmsRmtype,
                                            String businessStart,
                                            String businessEnd,
                                            String cardNo
    ) throws Exception {
        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/MinReserve/SingleTrialFitReserve";
        YhBasenfoRequestParamDto yhBasenfoRequestParamDto=new YhBasenfoRequestParamDto();
        yhBasenfoRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhBasenfoRequestParamDto.setHotelCode(pmsHotelCode);
        yhBasenfoRequestParamDto.setRoomType(pmsRmtype);
        yhBasenfoRequestParamDto.setStartDate(businessStart);
        yhBasenfoRequestParamDto.setEndDate(businessEnd);
        yhBasenfoRequestParamDto.setChannelCode("lfwx");
        yhBasenfoRequestParamDto.setRoomQuantity(1);
        yhBasenfoRequestParamDto.setCardNo(cardNo);
        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        String responseBody=HttpUtil.httpPost(uri,yhBasenfoRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        if(Objects.equals(2313,(Integer)map.get("Code"))){
            return false;
        }else{
            return true;
        }
    }

    @Override
    public YhOrderReturnDto orderYhReservation(String lhotelGroupCode,
                                               String pmsHotelGroupCode,
                                               String pmsHotelCode,
                                               String l2rNo,
                                               String pmsRmtype,
                                               ReservationBaseDto reservationBaseDto,
                                               List<ReservationPriceDto> reservationPriceDtos,
                                               GcOrderCouponDto gcOrderCouponDto)throws Exception{

        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/MinReserve/CreateFitReserve";
        PmsReservationOptionParamDto pmsReservationOptionParamDto=new PmsReservationOptionParamDto();
        pmsReservationOptionParamDto.setPbChannel(reservationBaseDto.getPbChannel());
        pmsReservationOptionParamDto.setResType(reservationBaseDto.getResType());
        PmsReservationOptionDto pmsReservationOptionDto= pmsReservationOptionFeignService.getPmsReservationOption(pmsReservationOptionParamDto.paramToMap()).getResultInfo();
        L2RAssert.objectNull(pmsReservationOptionDto,"预定必备参数不存在");
        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        List<YhDayPriceDto> dayPriceDtoList=reservationPriceDtos.stream().map(reservationPrice->{
            YhDayPriceDto dayPriceDto=new YhDayPriceDto();
            dayPriceDto.setActualRate(reservationPrice.getAmountPms().doubleValue());
            dayPriceDto.setBusinessDate(DateUtil.getStandarDateString(reservationPrice.getResDate()));
            dayPriceDto.setRateCode(reservationBaseDto.getPmsRatecode());
            dayPriceDto.setReason(DefaultValue.LINK2ROOM);
            dayPriceDto.setRoomRate(reservationPrice.getAmountBase().doubleValue());
            dayPriceDto.setRoomType(pmsRmtype);
            return dayPriceDto;
        }).collect(Collectors.toList());

        YhReservationRequestParamDto yhReservationRequestParamDto=new YhReservationRequestParamDto();
        yhReservationRequestParamDto.setActualRate(reservationPriceDtos.get(0).getAmountPms().doubleValue());
        yhReservationRequestParamDto.setArrivalDate(DateUtil.getStandarDateString(reservationBaseDto.getArr()));
        yhReservationRequestParamDto.setDepartureDate(DateUtil.getStandarDateString(reservationBaseDto.getDep()));
        yhReservationRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhReservationRequestParamDto.setHotelCode(pmsHotelCode);
        yhReservationRequestParamDto.setMarketCode(pmsReservationOptionDto.getMarket());
        yhReservationRequestParamDto.setName(reservationBaseDto.getRsvMan());
        yhReservationRequestParamDto.setRateCode(reservationBaseDto.getPmsRatecode());
        yhReservationRequestParamDto.setRemarks(reservationBaseDto.getRemark());
        yhReservationRequestParamDto.setReservePhone(reservationBaseDto.getRsvMobile());
        yhReservationRequestParamDto.setReserveSource(pmsReservationOptionDto.getReserveSource());
        yhReservationRequestParamDto.setReserveType(pmsReservationOptionDto.getSalesChannel());
        yhReservationRequestParamDto.setRoomQuantity(reservationBaseDto.getRoomNum());
        yhReservationRequestParamDto.setRoomRate(reservationPriceDtos.get(0).getAmountBase().doubleValue());
        yhReservationRequestParamDto.setRoomType(pmsRmtype);
        yhReservationRequestParamDto.setSourceCode(pmsReservationOptionDto.getSrc());
        yhReservationRequestParamDto.setDayPriceList(dayPriceDtoList);
        yhReservationRequestParamDto.setChannelCode("lfwx");
        yhReservationRequestParamDto.setParentReserveNo(l2rNo);
        yhReservationRequestParamDto.setCouponsCode(gcOrderCouponDto.getCouponNo());
        yhReservationRequestParamDto.setCouponsAmount(Optional.ofNullable(gcOrderCouponDto.getPresentValue()).map(value->Double.valueOf(value)).orElse(null));
        Optional.ofNullable(reservationBaseDto.getMemberNo()).map(TryExceptionUtil.of(value->{
            L2RYhMember queryYhMember=new L2RYhMember();
            queryYhMember.setLhotelGroupCode(reservationBaseDto.getLhotelGroupCode());
            queryYhMember.setL2RMemberNo(reservationBaseDto.getMemberNo());
            return commonService.findOneEQ(L2RYhMember.class,queryYhMember);
        })).ifPresent(TryExceptionUtil.of(
                l2RYhMember->{
                    boolean flag=this.checkYhMemberOrderDouble(lhotelGroupCode,
                            pmsHotelGroupCode,
                            pmsHotelCode,
                            pmsRmtype,
                            DateUtil.getWebDateString(reservationBaseDto.getArr()),
                            DateUtil.getWebDateString(reservationBaseDto.getDep()),
                            l2RYhMember.getCardNo());
                    if(flag){
                        yhReservationRequestParamDto.setRateCode(l2RYhMember.getCardLevel());
                        yhReservationRequestParamDto.setCardNo(l2RYhMember.getCardNo());
                        yhReservationRequestParamDto.setCardType(l2RYhMember.getCardLevel());
                    }else {
                        yhReservationRequestParamDto.setRateCode(l2RYhMember.getCardLevel());
                        yhReservationRequestParamDto.setComCardNo(l2RYhMember.getCardNo());
                        yhReservationRequestParamDto.setComCardType(l2RYhMember.getCardLevel());
                    }
                }
        )
        );
        String responseBody=HttpUtil.httpPost(uri,yhReservationRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        return Optional.ofNullable(map).filter(value->true==(boolean)map.get("Success")).map(value->{
            YhOrderReturnDto yhOrderReturnDto=new YhOrderReturnDto();
            Map data=(Map) map.get("Data");
            List<String> serialNoList= (List<String>) data.get("serialNoList");
            yhOrderReturnDto.setParentReserveNo((String)data.get("UnionSerial"));
            yhOrderReturnDto.setSerialNoList(serialNoList);
            return yhOrderReturnDto;
        }).orElseThrow(()-> {
            LogUtil.logger.error(JacksonUtil.beanToJson(yhReservationRequestParamDto));
            return new SoundwaveException(SoundwaveSysExceptionEnum.PMSRESER_SAVE_ERROR,(String)map.get("Message"));});
    }

    @Override
    public void cancelYhReservation(String lhotelGroupCode,
                                    String pmsHotelGroupCode,
                                    String pmsHotelCode,
                                    String crsNo)throws Exception{
        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/MinReserve/CancelFitReserve";
        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        YhReservationRequestParamDto yhReservationRequestParamDto=new YhReservationRequestParamDto();
        yhReservationRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhReservationRequestParamDto.setHotelCode(pmsHotelCode);
        yhReservationRequestParamDto.setUnionSerial(crsNo);
        String responseBody=HttpUtil.httpPost(uri,yhReservationRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        if(map.get("Success")!=null) {
            if (true != (boolean) map.get("Success")) {
                throw new SoundwaveException(SoundwaveSysExceptionEnum.PMSRESER_CANCEL_ERROR, (String) map.get("Message"));
            }
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.PMSRESER_CANCEL_ERROR, responseBody);
        }
    }

    @Override
    public List<YhReserveDto> queryYhReservation(String lhotelGroupCode,
                                    String pmsHotelGroupCode,
                                    String pmsHotelCode,
                                    String l2rNo)throws Exception{
        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/MinReserve/GetRoomResourceList";
        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        YhReservationRequestParamDto yhReservationRequestParamDto=new YhReservationRequestParamDto();
        yhReservationRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhReservationRequestParamDto.setHotelCode(pmsHotelCode);
        yhReservationRequestParamDto.setParentReserveNo(l2rNo);
        String responseBody=HttpUtil.httpPost(uri,yhReservationRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        return Optional.ofNullable(map).filter(value->true==(boolean)map.get("Success")).map(value->{
            List<Map<String,Object>> data=(List<Map<String,Object>>) map.get("Data");
            return data.stream().map(event->{
                YhReserveDto yhReserveDto=new YhReserveDto();
                yhReserveDto.setActualRate((Double)event.get("ActualRate"));
                yhReserveDto.setArrivalDate((String )event.get("ArrivalDate"));
                yhReserveDto.setDepartureDate((String )event.get("DepartureDate"));
                yhReserveDto.setGroupCode((String )event.get("GroupCode"));
                yhReserveDto.setHotelCode((String )event.get("HotelCode"));
                yhReserveDto.setHStatus((String )event.get("HStatus"));
                yhReserveDto.setName((String )event.get("Name"));
                yhReserveDto.setRoomRate((Double ) event.get("RoomRate"));
                yhReserveDto.setRoomType((String )event.get("RoomType"));
                yhReserveDto.setSerial((String )event.get("Serial"));
                yhReserveDto.setStatus((String )event.get("Status"));
                yhReserveDto.setPayamount((Double)event.get("Payamount"));
                yhReserveDto.setTotalAmount((Double)event.get("TotalAmount"));
                yhReserveDto.setRoomTypeName((String )event.get("RoomTypeName"));
                yhReserveDto.setCancelReserveRemarks((String )event.get("CancelReserveRemarks"));
                return yhReserveDto;
            }).collect(Collectors.toList());
        }).orElseThrow(()->new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_QUERY_RESERVE_ERROR,(String)map.get("Message")));
    }

    @Override
    public void saveYhReservationPay(String lhotelGroupCode,
                                     String pmsHotelGroupCode,
                                     String pmsHotelCode,
                                     String crsNo,
                                     String pmsResType,
                                     String taCode,
                                     BigDecimal amount)throws Exception{
        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/MinReserve/PrepayFitReserve";
        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        YhReservationRequestParamDto yhReservationRequestParamDto=new YhReservationRequestParamDto();
        yhReservationRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhReservationRequestParamDto.setHotelCode(pmsHotelCode);
        yhReservationRequestParamDto.setSerial(crsNo);
        yhReservationRequestParamDto.setPayamount(amount.doubleValue());
        yhReservationRequestParamDto.setPaymentType(pmsResType);
        yhReservationRequestParamDto.setFeeCode(taCode);
        String responseBody=HttpUtil.httpPost(uri,yhReservationRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        if(true!=(boolean)map.get("Success")){
            throw new SoundwaveException(SoundwaveSysExceptionEnum.PMSRESER_SAVE_PAY_ERROR,(String)map.get("Message"));
        }
    }

    @Override
    public List<YhRmtypePriceDto> getYhRoomPriceList(String lhotelGroupCode,
                                                     String pmsHotelGroupCode,
                                                     String pmsHotelCode,
                                                     String pmsRmtype,
                                                     String rateCode,
                                                     String businessStart,
                                                     String businessEnd) throws Exception {
        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/Cms/GetDailyRoomPriceList";
        YhBasenfoRequestParamDto yhBasenfoRequestParamDto=new YhBasenfoRequestParamDto();
        yhBasenfoRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhBasenfoRequestParamDto.setHotelCode(pmsHotelCode);
        yhBasenfoRequestParamDto.setRoomType(pmsRmtype);
        yhBasenfoRequestParamDto.setChannelCode("lfwx");
        yhBasenfoRequestParamDto.setStartDate(businessStart);
        yhBasenfoRequestParamDto.setEndDate(businessEnd);
        yhBasenfoRequestParamDto.setRateCode(rateCode);
        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        String responseBody=HttpUtil.httpPost(uri,yhBasenfoRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        if(true==(boolean)map.get("Success")){
            List<Map<String,Object>> dataMapList=(List<Map<String,Object>>)map.get("Data");
            return Optional.ofNullable(dataMapList).map(list->list.stream().map(event->{
                YhRmtypePriceDto yhRmtypePriceDto=new YhRmtypePriceDto();
                yhRmtypePriceDto.setHotelCode((String) event.get("HotelCode"));
                yhRmtypePriceDto.setGroupCode((String) event.get("GroupCode"));
                yhRmtypePriceDto.setBusinessDate(DateUtil.parseDateStandardFormat((String) event.get("BusinessDate")));
                yhRmtypePriceDto.setRoomTypeAilas((String) event.get("RoomTypeAilas"));
                yhRmtypePriceDto.setChannelCode((String) event.get("ChannelCode"));
                yhRmtypePriceDto.setRoomRate((Double) event.get("RoomRate"));
                if(new BigDecimal((Double) event.get("ActualRate")).compareTo(new BigDecimal(0))==0){
                    yhRmtypePriceDto.setActualRate((Double) event.get("RoomRate"));
                }else{
                    yhRmtypePriceDto.setActualRate((Double) event.get("ActualRate"));
                }
                yhRmtypePriceDto.setRoomType((String) event.get("RoomType"));
                return yhRmtypePriceDto;
            }).collect(Collectors.toList())).orElseGet(()->Collections.emptyList());
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_RMTYPEAVAIL_ERROR,(String)map.get("Message"));
        }
    }

    @Override
    public Map<String,List<YhModifyDataDto>> getModifyData(String lhotelGroupCode,
                                                           String pmsHotelGroupCode,
                                                           String pmsHotelCode,
                                                           String modifyDate) throws Exception {
        String clientIp= SysoptionUtil.getSysOption(lhotelGroupCode, YhPmsConstant.CONFIG_CATEGORY,YhPmsConstant.CONFIG_ITEM.BASE_CLIENTIP);
        String uri=clientIp+"/"+"api/Cms/GetHotelIncrementRoomPriceList";
        YhBasenfoRequestParamDto yhBasenfoRequestParamDto=new YhBasenfoRequestParamDto();
        yhBasenfoRequestParamDto.setGroupCode(pmsHotelGroupCode);
        yhBasenfoRequestParamDto.setHotelCode(pmsHotelCode);
        yhBasenfoRequestParamDto.setChannelCode("lfwx");
        yhBasenfoRequestParamDto.setStartDate(DateUtil.getNewFormatDateString(DateUtil.parseDateNoTime(new Date())));
        yhBasenfoRequestParamDto.setEndDate(DateUtil.getNewFormatDateString(DateUtil.parseDateNoTime(DateUtil.addDays(new Date(),365L))));
        yhBasenfoRequestParamDto.setModifyDate(modifyDate);
        Header[] headers = YhPmsUtil.getYhRequestHeader(lhotelGroupCode,YhPmsConstant.BASE_REQ );
        String responseBody=HttpUtil.httpPost(uri,yhBasenfoRequestParamDto,headers);
        Map map = JacksonUtil.jsonToBeanByJavaType(responseBody, Map.class, String.class,Object.class);
        if(true==(boolean)map.get("Success")){
            List<Map<String,Object>> dataMapList=(List<Map<String,Object>>)map.get("Data");
            return Optional.ofNullable(dataMapList).map(list->list.stream().map(event->{
                YhModifyDataDto yhModifyDataDto=new YhModifyDataDto();
                yhModifyDataDto.setHotelCode((String) event.get("HotelCode"));
                yhModifyDataDto.setGroupCode((String) event.get("GroupCode"));
                yhModifyDataDto.setRateCode((String) event.get("RateCode"));
                yhModifyDataDto.setRoomType((String) event.get("RoomType"));
                yhModifyDataDto.setStartDate(DateUtil.parseDateStandardFormat((String) event.get("StartDate")));
                yhModifyDataDto.setEndDate(DateUtil.parseDateStandardFormat((String) event.get("EndDate")));
                return yhModifyDataDto;
            }).collect(Collectors.groupingBy(value->value.getHotelCode()))).orElseGet(()->new HashMap<>());
        }else {
            throw new SoundwaveException(SoundwaveSysExceptionEnum.YHPMS_RMTYPEAVAIL_ERROR,(String)map.get("Message"));
        }
    }

}
